package cn.ahaoweb.drule.core.compile.translation;

import cn.ahaoweb.drule.core.compile.DefaultDruleCompile;
import cn.ahaoweb.drule.core.compile.enums.ConditionOperate;
import cn.ahaoweb.drule.core.compile.enums.ConditionRelated;
import cn.ahaoweb.drule.core.compile.structure.DruleBlock;
import cn.ahaoweb.drule.core.model.info.TreeNode;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import static cn.ahaoweb.drule.core.compile.constant.CompileSymbols.*;

/**
 * @Name: 默认中文转译器
 * @Description: 将规则块转译为中文，以便业务人员理解
 * @Author: wangzhonghao
 * @Date: 2025/3/1 16:27
 */
public class DruleChineseTranslation implements ChineseTranslation {

    /**
     * 规则集合
     */
    protected List<DruleBlock> rules;

    /**
     * 入参对象
     */
    protected TreeNode input;

    /**
     * 出参对象
     */
    protected TreeNode output;

    private DruleChineseTranslation(List<DruleBlock> rules, TreeNode input, TreeNode output) {
        this.rules = rules;
        this.input = input;
        this.output = output;
    }

    /**
     * 构建中文翻译对象
     *
     * @param rules  业务规则列表
     * @param input  入参对象结构
     * @param output 出参对象结构
     * @return 构建后的中文转译器
     */
    public static ChineseTranslation buildTranslation(List<DruleBlock> rules, TreeNode input, TreeNode output) {
        return new DruleChineseTranslation(rules, input, output);
    }

    /**
     * 转译
     *
     * @return
     */
    public List<TranslatedRuleText> translateRules() {
        if (rules != null && rules.size() > 0) {
            return rules.stream().map(this::blockToText).collect(Collectors.toList());
        }
        return new ArrayList<>();
    }

    /**
     * 将规则块转换为翻译后的文本。
     *
     * @param block 要转换的规则块
     * @return 转换后的翻译文本对象
     */
    public TranslatedRuleText blockToText(DruleBlock block) {
        TranslatedRuleText ruleText = transform(block);
        // 处理条件
        DruleBlock.When when = ruleText.getWhen();
        // 外层关系
        ConditionRelated related = when.getRelated();
        List<DruleBlock.ConditionGroup> groups = when.getGroups();
        if (groups != null) {
            for (int j = 0; j < groups.size(); j++) {
                DruleBlock.ConditionGroup group = groups.get(j);
                // 内层关系
                ConditionRelated rela = group.getRelated();
                List<DruleBlock.Condition> conditions = group.getConditions();
                if (conditions == null || conditions.isEmpty()) {
                    continue;
                }
                // 规则分组转中文
                StringBuilder text = new StringBuilder();
                if (j > 0) {
                    text.append(related.getChinese()).append(blank);
                }
                int size = conditions.size();
                if (size > 1) {
                    text.append(left_bracket).append(blank);
                }
                for (int i = 0; i < size; i++) {
                    DruleBlock.Condition condition = conditions.get(i);
                    String fieldName = condition.getFieldInfo().getFieldName() == null ?
                            condition.getFieldInfo().getFieldCode() : condition.getFieldInfo().getFieldName();
                    if (i > 0) {

                        text.append(blank)
                                .append(rela.getChinese())
                                .append(blank);
                    }
                    ConditionOperate op = condition.getOp();
                    if (ConditionOperate.right_contains.equals(op) || ConditionOperate.not_right_contains.equals(op)) {
                        text.append(op.op().processValue(condition, condition.getJudgeValue()))
                                .append(blank)
                                .append(op.getChinese())
                                .append(blank)
                                .append(fieldName);
                    } else {
                        text.append(fieldName)
                                .append(blank)
                                .append(op.getChinese())
                                .append(blank)
                                .append(op.op().processValue(condition, condition.getJudgeValue()));
                    }
                }
                if (size > 1) {
                    text.append(blank).append(right_bracket);
                }
                ruleText.getWhenText().add(text.toString());
            }
        }
        // 处理结果
        DruleBlock.Then then = ruleText.getThen();
        List<DruleBlock.Action> actions = then.getActions();
        if (actions != null) {
            for (int i = 0; i < actions.size(); i++) {
                DruleBlock.Action action = actions.get(i);
                DruleBlock.RuleFieldInfo fieldInfo = action.getFieldInfo();
                String field = fieldInfo.getFieldName() == null ? fieldInfo.getFieldCode() : fieldInfo.getFieldName();
                ruleText.getThenText().add(
                        new StringBuilder(field)
                                .append(blank)
                                .append("=")
                                .append(blank)
                                .append(DefaultDruleCompile.processActionValue(action))
                                .toString()
                );
            }
        }
        return ruleText;
    }

    /**
     * 将DruleBlock对象转换为TranslatedRuleText对象。
     *
     * @param block 需要转换的DruleBlock对象
     * @return 转换后的TranslatedRuleText对象
     */
    private static TranslatedRuleText transform(DruleBlock block) {
        TranslatedRuleText ruleText = new TranslatedRuleText();
        ruleText.setRuleName(block.getRuleName());
        ruleText.setEnabled(block.getEnabled());
        ruleText.setActivationGroup(block.getActivationGroup());
        ruleText.setRemark(block.getRemark());
        ruleText.setWhen(block.getWhen());
        ruleText.setThen(block.getThen());
        ruleText.setWhenText(new ArrayList<>());
        ruleText.setThenText(new ArrayList<>());
        return ruleText;
    }

    /**
     * 生成字符串列表
     * <p>
     * 此方法将翻译后的规则文本转换成字符串列表并返回。
     *
     * @return 包含翻译后规则文本的字符串列表
     */
    public List<String> generateStringList() {
        List<String> sl = new ArrayList<>();
        List<TranslatedRuleText> translatedRuleTexts = translateRules();
        for (TranslatedRuleText translatedRuleText : translatedRuleTexts) {
            sl.addAll(translatedRuleText.translate());
            sl.add(lf);
        }
        return sl;
    }

    /**
     * 生成文本内容
     * <p>
     * 此方法将翻译后的规则文本拼接成一个字符串并返回。
     *
     * @return 拼接后的文本内容
     */
    public String generateText() {
        StringBuilder text = new StringBuilder();
        List<TranslatedRuleText> translatedRuleTexts = translateRules();
        for (TranslatedRuleText translatedRuleText : translatedRuleTexts) {
            List<String> translate = translatedRuleText.translate();
            for (String s : translate) {
                text.append(s);
            }
            text.append(lf);
        }
        return text.toString();
    }

}
